package reservelayer

import (
    "time"
    "errors"
	"strconv"
	//"github.com/astaxie/beego"
	"dhfshop/models/reserve"
)

// 获取项目模板
type Template struct {
	PeriodSTLId   int64                  `json:"period_stl_id"`
	Name          string                 `json:"name"`
	EnName        string                 `json:"en_name"`
	PeriodNo      int                    `json:"period_no"`
	Status        int                    `json:"status"`
	TimeslotSTLs  []*reserve.TimeslotStl `json:"timeslot_stls"`
}

type TemplateHub struct {
	PartnerId   int64                `json:"partner_id"` 
	SchemaId    int64                `json:"schema_id"`
	PeriodSTLs  map[string]*Template `json:"period_stls"`
}

func GetModelCfg(partnerId, schemaId int64) (templateHub *TemplateHub, err error){
	templateHub = &TemplateHub{
			PartnerId:   partnerId,
			SchemaId:    schemaId,
			PeriodSTLs:  make(map[string]*Template),
		}
	templateHub.PartnerId = partnerId
	templateHub.SchemaId = schemaId
	//
	query := make(map[string]string)
	order_by := make(map[string]string)
	query["partner_id"] = strconv.FormatInt(partnerId, 10)
	query["schema_id"] = strconv.FormatInt(schemaId, 10)
	order_by["period_no"] = "asc"
	//查询周期模板是否私有
	if privateStls, err := reserve.GetAllPeriodSTLs(query, order_by); err == nil && len(privateStls) > 0 {
	   for _, value := range privateStls {
			if value.Status == 1 {
			    template := new(Template)
				template.PeriodSTLId = value.PeriodSTLId
				template.Name = value.Name
				template.EnName = value.EnName
				template.PeriodNo = value.PeriodNo
				template.Status = value.Status
				templateHub.PeriodSTLs[value.EnName] = template
			}
		}	
	} else {
	    query["schema_id"] = "0"
	    if publicStls, err := reserve.GetAllPeriodSTLs(query, order_by); err == nil {
		   //b, _ := json.Marshal(publicStls)
	       //beego.Debug("publicStls:", string(b))
		   for _, value := range publicStls {
				if value.Status == 1 {
					template := new(Template)
					template.PeriodSTLId = value.PeriodSTLId
					template.Name = value.Name
					template.EnName = value.EnName
					template.PeriodNo = value.PeriodNo
					template.Status = value.Status
					templateHub.PeriodSTLs[value.EnName] = template
				}
			}
		}
	}
	if len(templateHub.PeriodSTLs) == 0 {
	    err = errors.New("partner_id have no period:" + strconv.FormatInt(partnerId, 10))
		return 
	}
	for _, template := range templateHub.PeriodSTLs {
	    if lists, err := GroupTimeslotGet(partnerId, schemaId, template.PeriodSTLId); err == nil && len(lists) > 0  {
			template.TimeslotSTLs = lists
		} else {
		    if lists, err := GroupTimeslotGet(partnerId, schemaId, 0); err == nil {
				template.TimeslotSTLs = lists
			}
		}
        if len(template.TimeslotSTLs) < 1 {
		    if lists, err := GroupTimeslotGet(partnerId, 0, template.PeriodSTLId); err == nil && len(lists) > 0{
				template.TimeslotSTLs = lists
			} else {
				if lists, err := GroupTimeslotGet(partnerId, 0, 0); err == nil {
					template.TimeslotSTLs = lists
				}
			}
		}
	}
	return
}

func GroupTimeslotGet(partnerId, schemaId, periodSTLId int64) (lists []*reserve.TimeslotStl, err error){
	query := make(map[string]string)
	order_by := make(map[string]string)
	query["partner_id"] = strconv.FormatInt(partnerId, 10)
	query["schema_id"] = strconv.FormatInt(schemaId, 10)
	query["period_stl_id"] = strconv.FormatInt(periodSTLId, 10)
	order_by["timeslot_no"] = "asc"
	lists, err = reserve.GetAllTimeslotSTLs(query, order_by)
	return
}

// 实例化一天的数据
func ModelToDay(templateHub *TemplateHub, delayDay int) (period *reserve.Period, err error){
	srcDate := time.Now().Add(time.Duration(delayDay)*24*time.Hour)
	//year, month, day := srcDate.Date()
	//srcZeroDate := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	if periodId, _:= reserve.GetPeriodIdByDate(srcDate, templateHub.SchemaId); periodId > -1 {
	    if ok := reserve.ExistReservation(templateHub.SchemaId, periodId, 0); ok {
	        err = errors.New("reservation is exist")
			return
	    }
		reserve.DeletePeriodById(periodId)
	}
	weekDay := srcDate.Weekday().String()
	//
	//beego.Debug("delayDay:", delayDay, "srcDate:", srcDate, "weekDay:", weekDay)
	//
	if template, ok := templateHub.PeriodSTLs[weekDay]; ok {
	    period = new(reserve.Period)
		period.PartnerId = templateHub.PartnerId
		period.Schema, _ = reserve.GetSchemaById(templateHub.SchemaId)
		period.Name = template.Name
		period.Status = template.Status
		period.SourceAt = srcDate
		for _, slotSTL := range template.TimeslotSTLs {
		    timeslot := &reserve.Timeslot{
			    PartnerId: slotSTL.PartnerId,
			    Schema: period.Schema,
				TimeslotNo: slotSTL.TimeslotNo,
				Period: period,
				SourceAt: srcDate, 
				Start: slotSTL.Start,
				End: slotSTL.End,
				CurCount: 0,
				MaxCount: slotSTL.MaxCount,
				Status: 1,
			}
		    period.Timeslots = append(period.Timeslots, timeslot)
		}
	}else{
	    err = errors.New("there is not the weekday:" + strconv.FormatInt(templateHub.SchemaId,10))
	}
	return
}

// 实例化多天的数据
func ModelToMultiDay(templateHub *TemplateHub, reserveDays int) (periods []*reserve.Period, err error){
	periods = []*reserve.Period{}
	totalCountDays := 1
    for totalCountDays <= reserveDays {
		if period, err := ModelToDay(templateHub, totalCountDays); err == nil {
		    periods = append(periods, period)
		}
		totalCountDays++
    }
	for totalCountDays <= 30 {
	    //beego.Debug("totalCountDays:", totalCountDays)
		//beego.Debug("templateHub.SchemaId:", templateHub.SchemaId)
		DelExtraPeriod(templateHub.SchemaId, totalCountDays)
		totalCountDays++
    }
	return
}

// 删除一天的数据
func DelExtraPeriod(schemaId int64, delayDay int) (int64, error){
	srcDate := time.Now().Add(time.Duration(delayDay)*24*time.Hour)
	//year, month, day := srcDate.Date()
	//srcZeroDate := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	periodId, err := reserve.GetPeriodIdByDate(srcDate, schemaId)
	if err == nil && periodId > -1 {
		reserve.DeletePeriodById(periodId)
		return periodId, nil
	}
	return 0, err
}

